//本程序用于管理AvenirSQL 相当于终端控制台

const INI = require('ini');
const os = require('os');
const fs = require('fs');
const libcu = require('libcu');
const avenirsql = require('avenirsql');
const readLine = require('readline-sync');
const { timeStamp } = require('console');

async function giveFileName() {
    let fileName = "./run.ini"
    return fileName;
}

async function readIni(fileName) {
    let file = fs.readFileSync(fileName);
    var Info = INI.parse(file.toString());
    return Info;
}


async function main() {
    let ini = await readIni(await giveFileName());
    avenirsql.init({
        ip: ini.main.ip,
        user: 'root',
        password: 'lEaFYiagbRXmYFCrX5csNg==',            //通过加密获得的密码
        database: 'User',
        port: ini.main.port,
    })
    let sign = await safeConnect();
    while (1) {
        let command = readLine.question('AvenirSQL> ');
        let type = command.split(' ');
        if (type[0] === 'help' || !type[0]) {
            console.log(Usage());
        } else if (type[0] === 'addUser') {
            //如果是添加用户的话
            let name = type[1];
            let password = type[2];
            let auth = type[3];
            if (!name || !password) {
                console.log('lack of name or password');
                continue;
            }
            let sql = `create user ${name} ${password}`;
            !auth || (sql += ' ' + auth);
            console.log("cmd is : ", sql);
            let res = await safeDbOp(sql, sign.data);
            let check = await checkError(res);
            if (check.code == 1) {
                res = await safeDbOp(sql, check);
            }
            console.log(getMessage(res));
        } else if (type[0] === 'delUser') {
            let name = type[1];
            if (!name) {
                console.log('lack of name');
                continue;
            }
            if (name === 'root') {
                console.log('permission denied');
                continue;
            }
            let sql = `delete from User.user where name = '${name}'`;
            console.log("cmd is : ", sql);

            let res = await safeDbOp(sql, sign.data);
            let check = await checkError(res);
            if (check.code == 1) {
                res = await safeDbOp(sql, check);
            }
            console.log(getMessage(res));


        } else if (type[0] === 'exit' || type[0] === 'quit') {
            console.log('exited');
            process.exit(0);

        } else if (type[0] === 'login') {
            //重新连接
            sign = await safeConnect();
            console.log("login success ,sign:", sign.data || sign);
        } else {
            let sql = '';
            for (let i = 0; i < type.length; i++) {
                sql += type[i] + ' ';
            }
            sql = sql.trim(' ');
            let res = await safeDbOp(sql, sign.data);
            let check = await checkError(res);
            if (check.code == 1) {
                res = await safeDbOp(sql, check);
            }
            console.log(res);

        }
    }
    return 0;

}



//防止进程假死的函数
async function safeDbOp(sql, sign) {
    setTimeout(async () => {
        return "timeout";
    }, 3000);
    let res = await avenirsql.dbop(sql, sign.data);    //测试用 正式环境要改成sign.data
    return res;
}

//安全的连接操作
async function safeConnect() {
    setTimeout(async () => {
        return 'timeout';
    }, 3000);
    let sign = await avenirsql.connect();
    return sign;
}

function Usage() {
    const use = `\t欢迎使用AvenirSQL管理程序
    \tlogin:                                重新获得签名
    \taddUser [name] [password] [auth]:     新建用户
    \tdelUser [name]:                       删除用户
    \t[sql]:                                执行sql
    \texit:                                 退出`;
    return use;
}

function getMessage(res) {
    return res.message ? res.message : res
}

//检查返回值，超时就自动重发
async function checkError(response) {
    if (response && response.code == 2) {
        //返回值是2代表签名失效 重新登录即可
        let data = await safeConnect();
        if (data.code === 0) {
            data = data.data;
        } else {
            //说明重新登录也报错了 数据库故障
            return {
                code: -1,
                data: null,
            }
        }
        return {
            code: 1,
            data
        };
    } else if (response.code == 0) {
        return {
            code: 0,
            data: null
        };
    } else {
        return {
            code: -1,
            data: null,
        };  //其他错误 其实返回这个没啥用 只需要判断1 就行 
    }
}

main();